﻿using Microsoft.Xna.Framework;
using StardewModdingAPI;
using StardewModdingAPI.Events;
using StardewValley;
using StardewValley.Monsters;

namespace WorseGame.Content
{
    public class 害虫生成系统(IMonitor monitor, IModHelper helper)
    {
        public readonly IMonitor 监视器 = monitor;
        public readonly IModHelper 助手 = helper;
        private bool 已加载存档 = false;
        private readonly int 检查间隔分钟 = 1;
        private readonly int 最小作物数量 = 4;
        private readonly double 生成概率 = 0.3;
        private readonly int 最大害虫数量 = 5;
        private Dictionary<GameLocation, List<Vector2>> 区域害虫位置 = new();

        public void Initialize()
        {
            try
            {
                助手.Events.GameLoop.DayStarted += 每日开始;
                助手.Events.GameLoop.SaveLoaded += 存档加载;
                助手.Events.GameLoop.ReturnedToTitle += 返回标题;
                助手.Events.GameLoop.TimeChanged += 时间变化;
                助手.Events.GameLoop.UpdateTicked += 更新时;
            }
            catch (Exception ex)
            {
                监视器.Log($"初始化害虫系统时出错: {ex.Message}", LogLevel.Error);
            }
        }

        public void 存档加载(object? sender, SaveLoadedEventArgs e)
        {
            try
            {
                已加载存档 = true;
                监视器.Log("害虫系统已加载", LogLevel.Info);
            }
            catch (Exception ex)
            {
                监视器.Log($"存档加载时出错: {ex.Message}", LogLevel.Error);
            }
        }

        public void 返回标题(object? sender, ReturnedToTitleEventArgs e)
        {
            已加载存档 = false;
            区域害虫位置.Clear();
        }

        public void 每日开始(object? sender, DayStartedEventArgs e)
        {
            if (!已加载存档) return;

            try
            {
                区域害虫位置.Clear();
                检查害虫生成();
            }
            catch (Exception ex)
            {
                监视器.Log($"每日开始时出错: {ex.Message}", LogLevel.Error);
            }
        }

        public void 时间变化(object? sender, TimeChangedEventArgs e)
        {
            if (!已加载存档) return;

            try
            {
                if (e.NewTime % 检查间隔分钟 == 0)
                {
                    检查害虫生成();
                }
            }
            catch (Exception ex)
            {
                监视器.Log($"时间变化时出错: {ex.Message}", LogLevel.Error);
            }
        }

        public void 更新时(object? sender, UpdateTickedEventArgs e)
        {
            if (!已加载存档) return;

            try
            {
                if (e.IsMultipleOf(120))
                {
                    检查害虫破坏();
                }
            }
            catch (Exception ex)
            {
                监视器.Log($"更新时出错: {ex.Message}", LogLevel.Error);
            }
        }

        private void 检查害虫生成()
        {
            try
            {
                var 农场区域 = new List<GameLocation>
                {
                    Game1.getLocationFromName("Farm"),
                    Game1.getLocationFromName("IslandWest")
                };

                int 总生成数量 = 0;

                foreach (var 区域 in 农场区域)
                {
                    if (区域 == null) continue;

                    int 生成数量 = 检查区域害虫生成(区域);
                    总生成数量 += 生成数量;
                }

                if (总生成数量 > 0)
                {
                    Game1.addHUDMessage(new HUDMessage($"生成了 {总生成数量} 只害虫！及时清理防止作物被破坏", 2));
                }
            }
            catch (Exception ex)
            {
                监视器.Log($"检查害虫生成时出错: {ex.Message}", LogLevel.Error);
            }
        }

        private int 检查区域害虫生成(GameLocation 区域)
        {
            int 生成数量 = 0;

            try
            {
                var 已耕种位置 = 获取已耕种位置(区域);
                if (已耕种位置.Count < 最小作物数量) return 0;

                var 候选位置 = 获取害虫候选位置(区域, 已耕种位置);

                foreach (var 位置 in 候选位置)
                {
                    if (获取区域害虫数量(区域, 位置) >= 最大害虫数量)
                        continue;

                    if (Game1.random.NextDouble() < 生成概率)
                    {
                        生成害虫(区域, 位置);
                        生成数量++;
                    }
                }
            }
            catch (Exception ex)
            {
                监视器.Log($"检查区域害虫生成时出错: {ex.Message}", LogLevel.Error);
            }

            return 生成数量;
        }

        private List<Vector2> 获取已耕种位置(GameLocation 区域)
        {
            var 已耕种位置 = new List<Vector2>();

            try
            {
                foreach (var (位置, 地形特征) in 区域.terrainFeatures.Pairs)
                {
                    if (地形特征 is StardewValley.TerrainFeatures.HoeDirt 耕地 &&
                        耕地.crop != null &&
                        !耕地.crop.dead.Value)
                    {
                        已耕种位置.Add(位置);
                    }
                }
            }
            catch (Exception ex)
            {
                监视器.Log($"获取已耕种位置时出错: {ex.Message}", LogLevel.Error);
            }

            return 已耕种位置;
        }

        private List<Vector2> 获取害虫候选位置(GameLocation 区域, List<Vector2> 已耕种位置)
        {
            var 候选位置 = new List<Vector2>();
            var 已检查区域 = new HashSet<Vector2>();

            try
            {
                foreach (var 耕种位置 in 已耕种位置)
                {
                    Vector2 区域中心 = new Vector2(
                        (int)(耕种位置.X / 3) * 3 + 1,
                        (int)(耕种位置.Y / 3) * 3 + 1
                    );

                    if (已检查区域.Contains(区域中心))
                        continue;

                    已检查区域.Add(区域中心);

                    int 作物数量 = 计算区域内作物数量(已耕种位置, 区域中心);

                    if (作物数量 >= 最小作物数量)
                    {
                        Vector2? 害虫位置 = 获取随机害虫位置(区域, 区域中心);
                        if (害虫位置.HasValue)
                        {
                            候选位置.Add(害虫位置.Value);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                监视器.Log($"获取害虫候选位置时出错: {ex.Message}", LogLevel.Error);
            }

            return 候选位置;
        }

        private int 计算区域内作物数量(List<Vector2> 已耕种位置, Vector2 区域中心)
        {
            int 数量 = 0;

            try
            {
                for (int x = -1; x <= 1; x++)
                {
                    for (int y = -1; y <= 1; y++)
                    {
                        Vector2 检查位置 = new Vector2(区域中心.X + x, 区域中心.Y + y);
                        if (已耕种位置.Contains(检查位置))
                        {
                            数量++;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                监视器.Log($"计算区域内作物数量时出错: {ex.Message}", LogLevel.Error);
            }

            return 数量;
        }

        private Vector2? 获取随机害虫位置(GameLocation 区域, Vector2 区域中心)
        {
            var 空位置 = new List<Vector2>();

            try
            {
                for (int x = -1; x <= 1; x++)
                {
                    for (int y = -1; y <= 1; y++)
                    {
                        Vector2 检查位置 = new Vector2(区域中心.X + x, 区域中心.Y + y);
                        if (
                            !区域.Objects.ContainsKey(检查位置) &&
                            !区域.terrainFeatures.ContainsKey(检查位置))
                        {
                            空位置.Add(检查位置);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                监视器.Log($"获取随机害虫位置时出错: {ex.Message}", LogLevel.Error);
            }

            return 空位置.Count > 0 ? 空位置[Game1.random.Next(空位置.Count)] : null;
        }

        private void 生成害虫(GameLocation 区域, Vector2 位置)
        {
            try
            {
                Monster 害虫 = 创建安全害虫(位置);

                if (害虫 != null)
                {
                    区域.characters.Add(害虫);

                    if (!区域害虫位置.ContainsKey(区域))
                    {
                        区域害虫位置[区域] = new List<Vector2>();
                    }
                    区域害虫位置[区域].Add(位置);

                    区域.playSound("grunt");
                    显示生成效果(区域, 位置);

                    监视器.Log($"生成害虫在 {区域.Name} ({位置})", LogLevel.Info);
                }
            }
            catch (Exception ex)
            {
                监视器.Log($"生成害虫时出错: {ex.Message}", LogLevel.Error);
            }
        }

        private Monster 创建安全害虫(Vector2 位置)
        {
            try
            {
                Vector2 像素位置 = 位置 * 64f;
                if (Game1.random.NextDouble() < 0.5)
                {
                    return new Bug(像素位置, 0);
                }
                else
                {
                    return new Fly(像素位置, false);
                }
            }
            catch (Exception ex)
            {
                监视器.Log($"创建害虫时出错: {ex.Message}", LogLevel.Error);
                return null;
            }
        }

        private void 显示生成效果(GameLocation 区域, Vector2 位置)
        {
            try
            {
                for (int i = 0; i < 3; i++)
                {
                    区域.temporarySprites.Add(new TemporaryAnimatedSprite(
                        textureName: "LooseSprites\\Cursors",
                        sourceRect: new Rectangle(640, 784, 32, 32),
                        animationInterval: 80f,
                        animationLength: 4,
                        numberOfLoops: 2,
                        position: 位置 * 64f + new Vector2(16f, 16f),
                        flicker: false,
                        flipped: false,
                        layerDepth: 1f,
                        alphaFade: 0.02f,
                        color: Color.DarkRed,
                        scale: 1.5f,
                        scaleChange: 0f,
                        rotation: 0f,
                        rotationChange: 0f)
                    {
                        motion = new Vector2(Game1.random.Next(-1, 2), Game1.random.Next(-1, 2))
                    });
                }
            }
            catch (Exception ex)
            {
                监视器.Log($"显示生成效果时出错: {ex.Message}", LogLevel.Error);
            }
        }

        private void 检查害虫破坏()
        {
            try
            {
                foreach (var (区域, 害虫列表) in 区域害虫位置.ToList())
                {
                    if (区域 == null) continue;

                    var 要移除的害虫 = new List<Vector2>();

                    foreach (var 害虫位置 in 害虫列表)
                    {
                        if (区域.characters.Any(c => c?.Position == 害虫位置))
                        {
                            if (Game1.random.NextDouble() < 0.1)
                            {
                                尝试破坏作物(区域, 害虫位置);
                            }
                        }
                        else
                        {
                            要移除的害虫.Add(害虫位置);
                            continue;
                        }
                    }

                    foreach (var 位置 in 要移除的害虫)
                    {
                        害虫列表.Remove(位置);
                    }
                }
            }
            catch (Exception ex)
            {
                监视器.Log($"检查害虫破坏时出错: {ex.Message}", LogLevel.Error);
            }
        }

        private void 尝试破坏作物(GameLocation 区域, Vector2 害虫位置)
        {
            try
            {
                for (int x = -1; x <= 1; x++)
                {
                    for (int y = -1; y <= 1; y++)
                    {
                        Vector2 检查位置 = new Vector2(害虫位置.X + x, 害虫位置.Y + y);

                        if (区域.terrainFeatures.TryGetValue(检查位置, out var 地形特征))
                        {
                            if (地形特征 is StardewValley.TerrainFeatures.HoeDirt 耕地 &&
                                耕地.crop != null &&
                                !耕地.crop.dead.Value)
                            {
                                if (Game1.random.NextDouble() < 0.2)
                                {
                                    破坏作物(区域, 检查位置, 耕地);
                                    return;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                监视器.Log($"尝试破坏作物时出错: {ex.Message}", LogLevel.Error);
            }
        }

        private void 破坏作物(GameLocation 区域, Vector2 位置, StardewValley.TerrainFeatures.HoeDirt 耕地)
        {
            try
            {
                耕地.crop.dead.Value = true;
                区域.playSound("leafrustle");
                显示破坏效果(区域, 位置);

                Game1.addHUDMessage(new HUDMessage($"害虫破坏了作物！", 3));
            }
            catch (Exception ex)
            {
                监视器.Log($"破坏作物时出错: {ex.Message}", LogLevel.Error);
            }
        }

        private void 显示破坏效果(GameLocation 区域, Vector2 位置)
        {
            try
            {
                for (int i = 0; i < 5; i++)
                {
                    区域.temporarySprites.Add(new TemporaryAnimatedSprite(
                        textureName: "TileSheets\\debris",
                        sourceRect: new Rectangle(Game1.random.Next(2) * 16, 64, 16, 16),
                        animationInterval: 1000f,
                        animationLength: 1,
                        numberOfLoops: 0,
                        position: 位置 * 64f + new Vector2(32f, 32f),
                        flicker: false,
                        flipped: false,
                        layerDepth: 1f,
                        alphaFade: 0.01f,
                        color: Color.Brown,
                        scale: 2f,
                        scaleChange: 0f,
                        rotation: 0f,
                        rotationChange: 0f)
                    {
                        motion = new Vector2(Game1.random.Next(-3, 4), Game1.random.Next(-3, 4)),
                        acceleration = new Vector2(0f, 0.1f)
                    });
                }
            }
            catch (Exception ex)
            {
                监视器.Log($"显示破坏效果时出错: {ex.Message}", LogLevel.Error);
            }
        }

        private int 获取区域害虫数量(GameLocation 区域, Vector2 中心位置)
        {
            if (!区域害虫位置.ContainsKey(区域))
                return 0;

            int 数量 = 0;
            try
            {
                for (int x = -1; x <= 1; x++)
                {
                    for (int y = -1; y <= 1; y++)
                    {
                        Vector2 检查位置 = new Vector2(中心位置.X + x, 中心位置.Y + y);
                        if (区域害虫位置[区域].Contains(检查位置))
                        {
                            数量++;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                监视器.Log($"获取区域害虫数量时出错: {ex.Message}", LogLevel.Error);
            }

            return 数量;
        }

        public void 手动清理害虫()
        {
            if (!已加载存档) return;

            try
            {
                int 清理数量 = 0;

                foreach (var (区域, 害虫列表) in 区域害虫位置.ToList())
                {
                    if (区域 == null) continue;

                    var 要移除的害虫 = 区域.characters
                        .Where(c => c is Bug || c is Fly)
                        .ToList();

                    foreach (var 害虫 in 要移除的害虫)
                    {
                        区域.characters.Remove(害虫);
                        清理数量++;
                    }

                    害虫列表.Clear();
                }

                if (清理数量 > 0)
                {
                    Game1.addHUDMessage(new HUDMessage($"清理了 {清理数量} 只害虫", 1));
                }
            }
            catch (Exception ex)
            {
                监视器.Log($"手动清理害虫时出错: {ex.Message}", LogLevel.Error);
            }
        }
    }
}